home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume91
/
libraris
/
sregexp1
/
part01
/
clibrary.asm
< prev
next >
Wrap
Assembly Source File
|
1992-04-20
|
12KB
|
371 lines
;**************************************************************************
;* *
;* sregexp.library -- pattern matching run time library. *
;* *
;* *
;* Startup module: this is heavily copied from the sample.library *
;* in the RKM includes and autodocs. *
;* This also relies on some features of dice (in particular, registered *
;* args and features of the linker.) Be carefull if you make it with *
;* something else. *
;* *
;* Created: April 20, 1991 *
;* *
;**************************************************************************
CODE sregexp.start
INCLUDE "sregexpbase.i"
INCLUDE "exec/initializers.i"
INCLUDE "libraries/dos.i"
INCLUDE "exec/resident.i"
INCLUDE "exec/lists.i"
INCLUDE "exec/alerts.i"
INCLUDE "sreg_version.i"
;--------------------------------------------------------------------
; some generally usefull macros hiding _LVO's
;--------------------------------------------------------------------
CALLSYS macro
jsr _LVO\1(a6)
endm
XLIB macro
xref _LVO\1
endm
;--------------------------------------------------------------------
; Declare the library calls I use. The _LVO's are brought in
; from amiga.lib
;--------------------------------------------------------------------
XLIB OpenLibrary
XLIB CloseLibrary
XLIB Alert
XLIB FreeMem
XLIB Remove
;------ defined in Amiga.lib ------
xref _AbsExecBase
;------ defined in the c source, the id string of my library. ------
xref _idString
;--------------------------------------------------------------------
; Make some stuff visible for debuging.
;--------------------------------------------------------------------
xdef Init
xdef EndCode
xdef RomTag
xdef funcTable
xdef dataTable
xdef InitRoutine
xdef Open
xdef Close
xdef Expunge
xdef Reserved
;--------------------------------------------------------------------
; The links to the c code are in the file kludge.asm, because the
; assembler I use doesn't like to make symbols starting with a @.
; But thats what DICE starts it's regargs routines with, so...
; I make the links with das, which comes with dice.
;
; my library routines
;--------------------------------------------------------------------
xref parsesregexp
xref freesregexp
xref matchsregexp
xref matchnsregexp
xref iswild
xref anchorpath
xref nextfile
xref buildpath
xref freespathinfo
************************************************************************
* Ok, so much for the preamble, we can actually start to generate *
* some code now. The very first thing we should do is return an *
* error if someone tries to run us like a program, seeing as we *
* will be a perfectly legal AmigaDos load module. *
************************************************************************
Start:
moveq.l #-1,d0
rts
;--------------------------------------------------------------------
; Ok, here's what exec is going to look for to tell it that we are
; a library.
;--------------------------------------------------------------------
RomTag:
dc.w RTC_MATCHWORD ; magic
dc.l RomTag ; pointer back to magic
dc.l EndCode ; keep looking from here
dc.b RTF_AUTOINIT ; yes, autoinit me.
dc.b VERSION ; version number
dc.b NT_LIBRARY ; I'm a library
dc.b 0 ; no priority (typical)
dc.l sregexpname ; I have a name
dc.l _idString ; let's see some ID
dc.l Init ; start me up
;--------------------------------------------------------------------
; Ok, heres the table of 4 vectors exec is going to look for
; to autoinit me.
;
; We are word alligned here.
;--------------------------------------------------------------------
Init:
dc.l SregExpBase_SIZE ; size of library structure
dc.l funcTable ; table of all my routines.
dc.l dataTable ; LibStructure init data
dc.l InitRoutine ; Where to start me.
;--------------------------------------------------------------------
; This is the list of functions in my library.
;--------------------------------------------------------------------
funcTable:
dc.l Open
dc.l Close
dc.l Expunge
dc.l Reserved
; my own little gems.
dc.l parsesregexp
dc.l freesregexp
dc.l matchsregexp
dc.l matchnsregexp
dc.l iswild
dc.l anchorpath
dc.l nextfile
dc.l buildpath
dc.l freespathinfo
dc.l -1 ; end of the list.
;--------------------------------------------------------------------
; heres the stuff to initialise my Library structure.
;--------------------------------------------------------------------
dataTable:
INITBYTE LN_TYPE,NT_LIBRARY
INITLONG LN_NAME,sregexpname
INITBYTE LIB_FLAGS,LIBF_SUMUSED|LIBF_CHANGED
INITWORD LIB_VERSION,VERSION
INITWORD LIB_REVISION,REVISION
INITLONG LIB_IDSTRING,_idString
dc.l 0
*******************************************************************
* Ok, so now were really ready to get cooking. *
* This routine is called when the library is first linked into *
* the exec LibList. The Library structure has already been *
* initialised as per the dataTable instructions. *
* *
* When called, d0 has our library base and the segment list is *
* pointed to by a0; a6 is a pointer to SysBase. *
*******************************************************************
InitRoutine:
move.l a4,-(sp) ; put the lib pointer
move.l d0,a4 ; in a convinient place
move.l a6,sb_SysBase(a4) ; save SysBase
move.l a0,sb_SegList(a4) ; save our seglist
lea.l dosname(pc),a1 ; try and open up
moveq.l #0,d0 ; dos.library
CALLSYS OpenLibrary
move.l d0,sb_DOSBase(a4) ;save dos
bne.s 1$
ALERT AG_OpenLib|AO_DOSLib ; couldn't get dos!!!
;------- That's all there is to do. --------
1$
move.l a4,d0
move.l (sp)+,a4
rts
***********************************************************************
* So good so far. Now come the 4 standard library routines that *
* every good library must have. Each of these (in fact all of the *
* library calls) comes with the pointer to our library base in a6. *
***********************************************************************
;----------------------------------------------------------------------
; To open the library, all we have to do is up the count of current
; users and reset the delayed expunge flag. This returns the library
; pointer on d0 if we successfully opened (which is always the case).
;----------------------------------------------------------------------
Open:
addq.w #1,LIB_OPENCNT(a6)
bclr #LIBB_DELEXP,LIB_FLAGS(a6)
move.l a6,d0
rts
;----------------------------------------------------------------------
; When we close the library, we decrease the count of current
; users. If this has reached zeros, then we check the delayed
; expunge flag and clean up if it is set.
; If this routine returns 0 then that's that. If the return value
; is non-zero, it should be the segment pointer passed to the
; initialization routine, so we can be unloaded.
;----------------------------------------------------------------------
Close:
;--- set up the return value, which will be altered ---
;--- if we decide to do a delayed expunge. ---
moveq.l #0,d0
subq.w #1,LIB_OPENCNT(a6)
bne.s 1$
btst #LIBB_DELEXP,LIB_FLAGS(a6)
beq.s 1$
; --- take a shortcut into the Expunge routine that doesn't ---
; --- redo the tests we just did. ---
bsr.s ReallyExpunge
1$
; --- at this point, d0 is zero if we didn't expunge, otherwise ---
; --- it the address of our segment list. ---
rts
;----------------------------------------------------------------------
; Ok, so now we want to try to unload. First check if there
; are still any current openers, if so, just set the delayed
; expunge flag, and we'll go away when everyone closes us.
; Otherwise, clean up my resources and return the seg list to
; be unloaded
;----------------------------------------------------------------------
Expunge:
tst.w LIB_OPENCNT(a6)
beq.s ReallyExpunge
bset #LIBB_DELEXP,LIB_FLAGS(a6)
moveq.l #0,d0 ;don't unload me please
rts
ReallyExpunge:
movem.l d2/a5,-(sp)
move.l a6,a5
move.l sb_SysBase(a5),a6
move.l sb_SegList(a5),d2 ;save seglist.
move.l a5,a1 ;remove the library
REMOVE ;from the system list
move.l sb_DOSBase(a5),a1
CALLSYS CloseLibrary ;close dos.
moveq.l #0,d0
move.l a5,a1
move.w LIB_NEGSIZE(a5),d0
sub.l d0,a1
add.w LIB_POSSIZE(a5),d0
CALLSYS FreeMem ;free our library base.
move.l d2,d0 ;unload us.
movem.l (sp)+,d2/a5
rts
;----------------------------------------------------------------------
; This is the reserved vector. Just return 0.
;----------------------------------------------------------------------
Reserved:
moveq.l #0,d0
rts
**********************************************************************
* That's all of the standard stuff. As discussed above, the links *
* to the c code are in the file kludge.asm *
**********************************************************************
;----------------------------------------------------------------------
; Here are some stings used in the above. I put them at the end so
; so I don't have to worry about alignment.
;----------------------------------------------------------------------
dosname DOSNAME
sregexpname SREGEXPNAME
;----------------------------------------------------------------------
; The end of the code, where exec can start looking for more RomTag
; structures if it wants to.
;----------------------------------------------------------------------
EVEN
EndCode:
**********************************************************************
* *
* Now comes the clever part. Dice (and the others, I think) *
* references there global data from register a4. What I do *
* to have easy access to the Library structure data from the *
* c code, is transfer a6 to a4 on each library call and then *
* define the various things I want to access as offsets to *
* this, in effect, tricking dice into thinking they're global *
* variables. The real benifit of this is I don't need my own *
* custom links to the Exec and DOS library routines, because *
* there exists perfectly valid global variables SysBase and *
* DosBase. *
* *
**********************************************************************
DATA data
;---------------------------------------------------------------------
; This one is a little funny, it is the actual instance of the
; structure, and not a pointer to it. It should be declared in
; the c code as 'extern struct SregExpBase SregExpBase;' and then
; referenced with the '.' and not the '->'. This may not work
; I haven't tried it yet.
;----------------------------------------------------------------------
_SregExpBase equ 0
xdef _SregExpBase
;--- These are perfectly ordinary pointers ---
_SysBase equ sb_SysBase
xdef _SysBase
_DOSBase equ sb_DOSBase
xdef _DOSBase
end